<template>
  <view class="vertical-center">
    <uni-datetime-picker
      :ref="getWeekPickerRef"
      type="daterange"
      date-separator="."
      :clear-icon="false"
      :border="false"
      v-bind="$attrs"
      v-model="weekRange"
      @click="handleClick"
      @change="weekChange"
    />
    &nbsp;<uni-icons type="bottom" size="16" color="#091622" @click="openWeekPicer"></uni-icons>
  </view>
</template>

<script setup>
  import { ref, watch } from 'vue'
  import uniDatetimePicker from '../uni-datetime-picker/uni-datetime-picker.vue'

  /**
   * 接收父组件传参
   */
  const props = defineProps({
    // 开始日期
    modelValue: {
      type: [String, Number],
      default: ''
    },
    // 开始日期显示格式
    startFormat: {
      type: String,
      default: 'yyyy-MM-dd'
    },
    // 开始日期数据格式
    startValueFormat: {
      type: String,
      default: ''
    },
    // 结束日期
    endDate: {
      type: [String, Number],
      default: ''
    },
    // 结束日期显示格式
    endFormat: {
      type: String,
      default: 'yyyy-MM-dd'
    },
    // 结束日期数据格式
    endValueFormat: {
      type: String,
      default: ''
    },
  })

  /**
   * 按周业务
   */
  const weekRange = ref([props.modelValue, props.endDate])
  const weekPicker = ref(null)

  const getWeekPickerRef = e => weekPicker.value = e

  const openWeekPicer = () => weekPicker.value.show()

  watch(() => [props.modelValue, props.endDate], () => weekRange.value = [props.modelValue, props.endDate])

  const handleClick = date => {
    if (typeof date === 'string') { // 解决点击事件重复触发的问题
      const weekStart = getWeekFirst({format: props.startFormat, date: new Date(date)})
      const weekEnd = getWeekLast({format: props.endFormat, date: new Date(date)})
      weekRange.value = [weekStart, weekEnd]
    }
  }

  // 日期格式化
  const formatDate = ({date = new Date(), format = 'yyyy/MM/dd hh:mm:ss'} = {}) => {
  	if (date !== 'Invalid Date') {
  		const o = {
  			'M+': date.getMonth() + 1, // month
  			'd+': date.getDate(), // day
  			'h+': date.getHours(), // hour
  			'm+': date.getMinutes(), // minute
  			's+': date.getSeconds(), // second
  			'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
  			'S': date.getMilliseconds() // millisecond
  		}
  		if (/(y+)/.test(format)) {
  			format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  		}
  		for (let k in o) {
  			if (new RegExp('(' + k + ')').test(format)) {
  				format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
  			}
  		}
  		return format
  	}
  	return ''
  }

  // 获取指定日期所在周的周一日期
  const getWeekFirst = ({date = new Date(), format = 'yyyy/MM/dd hh:mm:ss'} = {}) => {
    let day = date.getDay()
    if (day === 1) { // 若是周一直接返回格式化日期
      return formatDate({
        date,
        format
      })
    }
    if (!day) {
      day = 7
    }
    const millisecondDiff = (day - 1) * 24 * 60 * 60 * 1000 // 周一距离当前日期的毫秒数
    return formatDate({
      date: new Date(date.getTime() - millisecondDiff),
      format
    })
  }

	// 获取指定日期所在周的周日日期
  const getWeekLast = ({date = new Date(), format = 'yyyy/MM/dd hh:mm:ss'} = {}) => {
    const day = date.getDay()
    if (day === 0) { // 若是周日直接返回格式化日期
      return formatDate({
        date,
        format
      })
    }
    const millisecondDiff = (7 - day) * 24 * 60 * 60 * 1000 // 周日距离当前日期的毫秒数
    return formatDate({
      date: new Date(date.getTime() + millisecondDiff),
      format
    })
  }

  /**
   * 事件处理
   */
  const emit = defineEmits(['update:modelValue', 'update:endDate', 'change'])

  const weekChange = ([weekStart, weekEnd]) => {
    const weekStartDate = formatDate({
      date: new Date(weekStart),
      format: props.startValueFormat || props.startFormat
    })
    const weekEndDate = formatDate({
      date: new Date(weekEnd),
      format: props.endValueFormat || props.endFormat
    })
    emit('update:modelValue', weekStartDate)
    emit('update:endDate', weekEndDate)
    emit('change', [weekStartDate, weekEndDate])
  }
</script>

<style lang="scss">
  /* 修改组件默认样式 */
  :deep(.uni-date__x-input),
  :deep(.range-separator) {
    height: auto;
    font-size: 32rpx;
    color: #091622;
    line-height: 1.1;
  }
  :deep(.uni-date),
  :deep(.uni-date__x-input) {
    flex: 0 1 58%;
  }
  :deep(.uni-date-x) {
    justify-content: flex-start;
  }
  :deep(.icon-calendar) {
    display: none;
  }
  :deep(.uni-calendar-item__weeks-box .uni-calendar-item--checked.uni-calendar-item--checked-range-text) {
    border: none;
    background-color: #f6f7fc;
    .uni-calendar-item--checked-text {
      color: #333;
    }
  }
</style>
